package edu.kit.aifb.ldstream.learner.tasks.mod;

import org.openrdf.query.MalformedQueryException;
import org.openrdf.query.QueryEvaluationException;
import org.openrdf.query.QueryLanguage;
import org.openrdf.query.TupleQuery;
import org.openrdf.query.TupleQueryResult;
import org.openrdf.repository.RepositoryException;
import org.semanticweb.yars.nx.namespace.RDF;

import edu.kit.aifb.ldstream.env.Environment;

public class ModNumTriplesTask extends LearnerTask{

	private ModStatistics stats;
	
	public ModNumTriplesTask(ModStatistics stats){
		this.stats = stats;
	}
	
	@Override
	public void run() {
		if(Environment.LOGGING){
			Environment.log.info("Started to collect statistics");
		}
		startup();
		// -1 because of the added numEvents triple
		int numTriples = countNumTriples() - 1;
		this.stats.setNumTriples(numTriples);
		int numTypes = numTypes();
		this.stats.setNumTypes(numTypes);
		int numInstances = numInstances();
		this.stats.setNumInstances(numInstances);
		
		shutdown();
		if(Environment.LOGGING){
			Environment.log.info("Finished collecting statistics. #Triples: " + numTriples + " #Types: " + numTypes + " #Instances: " + numInstances
									+ " numEvents " + this.stats.getNumEvents());
		}
	}

	private int countNumTriples(){
		int numTriples = 0;
	//	String query = "SELECT (COUNT(?pred) AS ?num) FROM <" + Environment.STREAM_CONTEXT_URI.stringValue() +"> WHERE{  ?x ?pred ?y .}";
		String query = "SELECT (COUNT(?pred) AS ?num)  WHERE{  ?x ?pred ?y .}";
		try {
			TupleQuery tupleQuery = this.con.prepareTupleQuery(QueryLanguage.SPARQL, query);
			TupleQueryResult result = tupleQuery.evaluate();
			numTriples = Integer.parseInt(result.next().getBinding("num").getValue().stringValue());
			result.close();
		} catch (RepositoryException e) {
			e.printStackTrace();
		} catch (MalformedQueryException e) {
			e.printStackTrace();
		} catch (QueryEvaluationException e) {
			e.printStackTrace();
		}
		return numTriples;
	}

	private int numTypes(){
		int numTypes = 0;
		/*	
	  	String query = "SELECT (COUNT(DISTINCT(?type)) AS ?numTypes) FROM <" 
				+ Environment.STREAM_CONTEXT_URI.stringValue() + ">"
				+ " WHERE {?x "+ RDF.TYPE.toN3() +" ?type FILTER( !isBLANK(?x)) }";
		*/
		StringBuilder query = new StringBuilder("SELECT (COUNT(DISTINCT(?type)) AS ?numTypes) WHERE {?x ")
								.append(RDF.TYPE.toN3())
								.append(" ?type FILTER( !isBLANK(?x)) }");
		try {
			TupleQuery tupleQuery = this.con.prepareTupleQuery(QueryLanguage.SPARQL, query.toString());
			TupleQueryResult result = tupleQuery.evaluate();
			numTypes = Integer.parseInt(result.next().getBinding("numTypes").getValue().stringValue());
			result.close();
		} catch (RepositoryException e) {
			e.printStackTrace();
		} catch (MalformedQueryException e) {
			e.printStackTrace();
		} catch (QueryEvaluationException e) {
			e.printStackTrace();
		}
		return numTypes;

	}

	private int numInstances(){
		int numInstances = 0;
		/*
		String query = "Select (COUNT(DISTINCT(?instance)) AS ?numInstances) FROM <" 
						+ Environment.STREAM_CONTEXT_URI.stringValue() + "> WHERE {?instance " + RDF.TYPE.toN3() +" ?type "
						+ "FILTER(!isBLANK(?instance)) }";
		*/
		
		StringBuilder query = new StringBuilder("Select (COUNT(DISTINCT(?instance)) AS ?numInstances) WHERE {?instance ")
								.append(RDF.TYPE.toN3())
								.append(" ?type ")
								.append("FILTER(!isBLANK(?instance)) }");
		
		try {
			TupleQuery tupleQuery = this.con.prepareTupleQuery(QueryLanguage.SPARQL, query.toString());
			TupleQueryResult result = tupleQuery.evaluate();
			numInstances = Integer.parseInt(result.next().getBinding("numInstances").getValue().stringValue());
			result.close();
		} catch (RepositoryException e) {
			e.printStackTrace();
		} catch (MalformedQueryException e) {
			e.printStackTrace();
		} catch (QueryEvaluationException e) {
			e.printStackTrace();
		}
		return numInstances;
	}
}
